package com.afdor.rws.event.driven.channel;

import com.afdor.rws.event.driven.Serialization;
import com.afdor.rws.event.driven.channel.consumer.handler.EventHandler;
import com.afdor.rws.event.driven.channel.consumer.handler.EventRetryStrategy;
import com.afdor.rws.event.driven.channel.transaction.ChannelTransactionItem;
import com.afdor.rws.event.driven.config.EventChannelConfig;
import com.afdor.rws.event.driven.config.EventConsumerConfig;
import com.afdor.rws.event.driven.entities.Event;
import com.afdor.rws.event.driven.entities.holder.CallbackEvent;
import com.afdor.rws.event.driven.entities.holder.ResultEvent;
import lombok.NonNull;

import java.util.List;

/**
 * 事件传递通道
 *
 * @author 悭梵
 * @date Created in 2018-08-08 10:39
 */
public interface ChannelProvider {
    /**
     * 通道初始化方法
     */
    <T extends ChannelProvider> T init();

    /**
     * 停止执行
     */
    void destroy();

    /**
     * 获取配置信息
     *
     * @return
     */
    <C extends EventChannelConfig> C getConfig();

    /**
     * 这是配置信息
     *
     * @param config
     * @param <T>
     * @return
     */
    <T extends ChannelProvider, C extends EventChannelConfig> T setConfig(C config);

    /**
     * 获取事件源名称
     *
     * @return
     */
    String getEventSourceName();

    /**
     * 设置事件源名称
     *
     * @param eventSourceName
     * @return
     */
    <T extends ChannelProvider> T setEventSourceName(String eventSourceName);

    /**
     * 返回序列化器-用于事件传输
     *
     * @return
     */
    Serialization getSerialization();

    /**
     * 设置序列化器-用于事件传输
     *
     * @param serialization
     * @return
     */
    <T extends ChannelProvider> T setSerialization(Serialization serialization);

    /**
     * 订阅事件
     *
     * @param eventHandler 事件处理器
     */
    <T extends ChannelProvider> T subscribe(EventConsumerConfig eventConsumerConfig, EventHandler eventHandler);

    /**
     * 订阅事件
     *
     * @param eventHandler 事件处理器
     */
    <T extends ChannelProvider> T subscribe(EventConsumerConfig eventConsumerConfig, EventHandler eventHandler, EventRetryStrategy eventRetryStrategy);

    /**
     * 通过生产者，发送单条事件
     *
     * @param event 事件对象
     */
    <V> ResultEvent<V> sendEvent(@NonNull Event event);

    /**
     * 发送异步消息
     *
     * @param event
     * @return
     */
    void sendAsyncEvent(@NonNull Event event);

    /**
     * 异步发送消息并成功回调同步处理
     *
     * @param callbackEvent
     * @param <V>           返回结果对象
     * @return
     */
    <V> void asyncSendEvent(@NonNull CallbackEvent callbackEvent);

    /**
     * 批量发送异步消息
     *
     * @param eventList
     * @return
     */
    void batchSendAsyncEvent(@NonNull List<Event> eventList);

    /**
     * 开启一个新事物，多次调用会返回多个不同的值
     *
     * @return 返回事物标识。为使用线程本地变量来存此标识，避免多线程切换带来的问题，可放心使用线程池
     */
    ChannelTransactionItem newChannelTransaction();

    /**
     * 添加到发送队列事件消息
     *
     * @param event
     * @param channelTransactionId 事物标识
     */
    void addEvent(String channelTransactionId, Event event);

    /**
     * 将添加到队列中的事件统一提交
     *
     * @param channelTransactionId 事物标识
     * @return
     */
    boolean commit(String channelTransactionId);

    /**
     * 将添加到队列中的事件统一回滚
     *
     * @param channelTransactionId 事物标识
     */
    void rollback(String channelTransactionId);

}
